package com.engine.salary.service.impl;

import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.config.SalaryElogConfig;
import com.engine.hrmelog.entity.dto.LoggerContext;
import com.engine.salary.entity.datacollection.DataCollectionEmployee;
import com.engine.salary.entity.extemp.dto.ExtEmpDTO;
import com.engine.salary.entity.extemp.param.ExtEmpImportParam;
import com.engine.salary.entity.extemp.param.ExtEmpQueryParam;
import com.engine.salary.entity.extemp.param.ExtEmpSaveParam;
import com.engine.salary.entity.extemp.po.ExtEmpPO;
import com.engine.salary.entity.hrm.DeptInfo;
import com.engine.salary.entity.hrm.SubCompanyInfo;
import com.engine.salary.entity.salarysob.param.SalarySobRangeEmpQueryParam;
import com.engine.salary.enums.OperateTypeEnum;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.mapper.datacollection.EmployMapper;
import com.engine.salary.mapper.extemp.ExternalEmployeeMapper;
import com.engine.salary.service.ExtEmpService;
import com.engine.salary.service.SalaryEmployeeService;
import com.engine.salary.util.SalaryDateUtil;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.db.IdGenerator;
import com.engine.salary.util.db.MapperProxyFactory;
import com.engine.salary.util.excel.ExcelComment;
import com.engine.salary.util.excel.ExcelParseHelper;
import com.engine.salary.util.excel.ExcelSupport;
import com.engine.salary.util.excel.ExcelUtilPlus;
import com.engine.salary.util.page.PageInfo;
import com.engine.salary.util.page.SalaryPageUtil;
import com.engine.salary.util.valid.ValidUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import weaver.file.ImageFileManager;
import weaver.general.Util;
import weaver.hrm.User;
import weaver.hrm.company.DepartmentComInfo;

import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

import static com.engine.salary.util.excel.ExcelSupport.EXCEL_TYPE_XLSX;

/**
 * 累计专项
 * <p>Copyright: Copyright (c) 2022</p>
 * <p>Company: 泛微软件</p>
 *
 * @author qiantao
 * @version 1.0
 **/
public class ExtEmpServiceImpl extends Service implements ExtEmpService {


    private ExternalEmployeeMapper getExternalEmployeeMapper() {
        return MapperProxyFactory.getProxy(ExternalEmployeeMapper.class);
    }

    private SalaryEmployeeService getSalaryEmployeeService(User user) {
        return ServiceUtil.getService(SalaryEmployeeServiceImpl.class, user);
    }

    private EmployMapper getEmployMapper() {
        return MapperProxyFactory.getProxy(EmployMapper.class);
    }

    @Override
    public List<ExtEmpPO> list(ExtEmpQueryParam param) {
        return getExternalEmployeeMapper().listSome(ExtEmpPO.builder().username(param.getUsername()).build());
    }

    @Override
    public PageInfo<ExtEmpDTO> listPage(ExtEmpQueryParam param) {
        List<ExtEmpPO> extEmpPOS = list(param);

        List<ExtEmpDTO> list = extEmpPOS.stream().map(po -> {
            return ExtEmpDTO.builder()
                    .id(po.getId())
                    .username(po.getUsername())
                    .departmentName(po.getDepartmentName())
                    .subcompanyName(po.getSubcompanyName())
                    .companystartdate(po.getCompanystartdate())
                    .workcode(po.getWorkcode())
                    .build();
        }).collect(Collectors.toList());

        return SalaryPageUtil.buildPage(param.getCurrent(), param.getPageSize(), list, ExtEmpDTO.class);

    }

    @Override
    public void save(ExtEmpSaveParam param) {

        List<ExtEmpPO> extEmpPOS = getExternalEmployeeMapper().listSome(ExtEmpPO.builder().username(param.getUsername()).build());
        if (CollectionUtils.isNotEmpty(extEmpPOS)) {
            throw new SalaryRunTimeException("姓名已存在！");
        }

        ExtEmpPO po = new ExtEmpPO();
        BeanUtils.copyProperties(param, po);

        po.setId(IdGenerator.generate());
        po.setStatus("2");
        po.setCreator((long) user.getUID());
        po.setModifier((long) user.getUID());
        Date now = new Date();
        po.setCreateTime(now);
        po.setUpdateTime(now);
        po.setDeleteType(0);

        getExternalEmployeeMapper().insertIgnoreNull(po);

        // 记录日志
        LoggerContext<ExtEmpPO> loggerContext = new LoggerContext<>();
        loggerContext.setUser(user);
        loggerContext.setTargetId(String.valueOf(po.getId()));
        loggerContext.setTargetName(po.getUsername());
        loggerContext.setOperateType(OperateTypeEnum.ADD.getValue());
        loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "新增非系统人员"));
        loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "新增非系统人员") + ": " + po.getUsername());
        loggerContext.setNewValues(po);
        SalaryElogConfig.extEmployeeLoggerTemplate.write(loggerContext);
    }

    @Override
    public void update(ExtEmpSaveParam param) {

        ExtEmpPO oldPO = getExternalEmployeeMapper().getById(param.getId());
        if (!StringUtils.equals(oldPO.getUsername(), param.getUsername())) {
            List<ExtEmpPO> extEmpPOS = getExternalEmployeeMapper().listSome(ExtEmpPO.builder().username(param.getUsername()).build());
            if (CollectionUtils.isNotEmpty(extEmpPOS)) {
                throw new SalaryRunTimeException("姓名已存在！");
            }
        }

        ExtEmpPO po = new ExtEmpPO();
        BeanUtils.copyProperties(param, po);

        po.setModifier((long) user.getUID());
        Date now = new Date();
        po.setUpdateTime(now);

        getExternalEmployeeMapper().updateIgnoreNull(po);
        ExtEmpPO byId = getExternalEmployeeMapper().getById(po.getId());

        // 记录日志
        LoggerContext<ExtEmpPO> loggerContext = new LoggerContext<>();
        loggerContext.setUser(user);
        loggerContext.setTargetId(String.valueOf(byId.getId()));
        loggerContext.setTargetName(byId.getUsername());
        loggerContext.setOperateType(OperateTypeEnum.UPDATE.getValue());
        loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "编辑非系统人员"));
        loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "编辑非系统人员") + ": " + byId.getUsername());
        loggerContext.setOldValues(oldPO);
        loggerContext.setNewValues(byId);
        SalaryElogConfig.extEmployeeLoggerTemplate.write(loggerContext);
    }

    @Override
    public void delete(Collection<Long> ids) {
        if (CollectionUtils.isNotEmpty(ids)) {
            List<ExtEmpPO> extEmpPOS = getExternalEmployeeMapper().listSome(ExtEmpPO.builder().ids(ids).build());
            ids.forEach(getExternalEmployeeMapper()::delete);
            // 记录日志
            extEmpPOS.forEach(extEmployeePO -> {
                LoggerContext<ExtEmpPO> loggerContext = new LoggerContext<>();
                loggerContext.setUser(user);
                loggerContext.setTargetId(String.valueOf(extEmployeePO.getId()));
                loggerContext.setTargetName(extEmployeePO.getUsername());
                loggerContext.setOperateType(OperateTypeEnum.DELETE.getValue());
                loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "删除非系统人员"));
                loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "删除非系统人员") + ": " + extEmployeePO.getUsername());
                loggerContext.setOldValues(extEmployeePO);
                SalaryElogConfig.extEmployeeLoggerTemplate.write(loggerContext);
            });
        }
    }

    @Override
    public DataCollectionEmployee getEmployeeById(Long id) {
        ExtEmpPO po = getExternalEmployeeMapper().getById(id);
        return cover(po);
    }

    @Override
    public List<DataCollectionEmployee> getEmployeeByIds(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return new ArrayList<>();
        }
        List<ExtEmpPO> extEmpPOS = new ArrayList<>();
        List<List<Long>> partition = Lists.partition(ids, 500);
        partition.forEach(list -> extEmpPOS.addAll(getExternalEmployeeMapper().listSome(ExtEmpPO.builder().ids(list).build())));
        return coverList(extEmpPOS);

    }

    @Override
    public List<DataCollectionEmployee> listByParams(List<SalarySobRangeEmpQueryParam> includeQueryParams) {
        List<DataCollectionEmployee> emps = new ArrayList<>();
        List<List<SalarySobRangeEmpQueryParam>> partition = Lists.partition(includeQueryParams, 100);
        partition.forEach(list -> {
            emps.addAll(getExternalEmployeeMapper().listByParams(list));
        });
        return emps;
    }

    @Override
    public List<DataCollectionEmployee> listEmployee() {
        return getExternalEmployeeMapper().listEmployee();
    }

    @Override
    public Collection<DataCollectionEmployee> getEmployeeByIdsAll(List<Long> ids) {
        List<DataCollectionEmployee> employeeList = new ArrayList<>();
        List<List<Long>> partition = Lists.partition(ids, 1000);
        partition.forEach(e -> {
            List<DataCollectionEmployee> employeeByIdsAll = getExternalEmployeeMapper().getEmployeeByIdsAll(e);
            employeeList.addAll(employeeByIdsAll);
        });
        return employeeList;
    }

    @Override
    public Collection<DataCollectionEmployee> listAllForReport() {
        return getExternalEmployeeMapper().listAllForReport();
    }

    @Override
    public ExtEmpPO getById(Long id) {
        ExtEmpPO po = getExternalEmployeeMapper().getById(id);
        if (po != null) {
            if (po.getDepartmentId() != null) {
                List<DeptInfo> deptInfoList = getSalaryEmployeeService(user).getDeptInfoList(Collections.singletonList(po.getDepartmentId()));
                if (CollectionUtils.isNotEmpty(deptInfoList)) {
                    po.setDepartmentOrgName(deptInfoList.get(0).getName());
                }
            }
            if (po.getSubcompanyId() != null) {
                List<SubCompanyInfo> subInfoList = getSalaryEmployeeService(user).getSubCompanyInfoList(Collections.singletonList(po.getSubcompanyId()));
                if (CollectionUtils.isNotEmpty(subInfoList)) {
                    po.setSubcompanyOrgName(subInfoList.get(0).getName());
                }
            }
        }
        return po;
    }


    public DataCollectionEmployee cover(ExtEmpPO extPo) {
        if (extPo == null) {
            return null;
        }
        DataCollectionEmployee employee = new DataCollectionEmployee();
        BeanUtils.copyProperties(extPo, employee);
        employee.setEmployeeId(extPo.getId());
        employee.setExtEmp(true);
        return employee;
    }

    public List<DataCollectionEmployee> coverList(List<ExtEmpPO> extEmps) {
        if (CollectionUtils.isEmpty(extEmps)) {
            return new ArrayList<>();
        }

        return extEmps.stream().map(emp -> {
            DataCollectionEmployee employee = new DataCollectionEmployee();
            BeanUtils.copyProperties(emp, employee);
            employee.setEmployeeId(emp.getId());
            employee.setExtEmp(true);
            return employee;
        }).collect(Collectors.toList());
    }

    @Override
    public XSSFWorkbook exportImportTemplate() {

        // 模板表头
        List<Object> headerList = Lists.newArrayList(
                SalaryI18nUtil.getI18nLabel(25034, "姓名"),
                SalaryI18nUtil.getI18nLabel(27511, "部门"),
                SalaryI18nUtil.getI18nLabel(33553, "分部"),
                SalaryI18nUtil.getI18nLabel(1516, "入职日期"),
                SalaryI18nUtil.getI18nLabel(125238, "手机号"),
                SalaryI18nUtil.getI18nLabel(1933, "工号"),
                SalaryI18nUtil.getI18nLabel(1887, "身份证号码"),
                SalaryI18nUtil.getI18nLabel(0, "本人开户的银行卡卡号"),
                SalaryI18nUtil.getI18nLabel(0, "本人开户的银行卡开户支行全称"));
        List<String> dataIndexList = Lists.newArrayList("username", "departmentName", "subcompanyName", "companystartdate", "mobile", "workcode", "idNo", "bankCardNum", "bankName");

        // excel导出的数据
        List<List<Object>> rows = new ArrayList<>();
        rows.add(headerList);

        // 注释
        List<ExcelComment> excelComments = Lists.newArrayList();
        excelComments.add(new ExcelComment(0, 0, 1, 2, SalaryI18nUtil.getI18nLabel(30036, "必填")));
        excelComments.add(new ExcelComment(3, 0, 4, 2, SalaryI18nUtil.getI18nLabel(542348, "格式样例为'2022-01-01'、'2022/1/1'")));

        String sheetName = "非系统人员导入模板";
        return ExcelUtilPlus.genWorkbookV2(rows, sheetName, excelComments);
    }

    @Override
    public Map<String, Object> previewImportExtEmp(ExtEmpImportParam param) {
        //参数校验
        ValidUtil.doValidator(param);

        Map<String, Object> map = new HashMap<>();

        InputStream fileInputStream = null;
        try {
            fileInputStream = ImageFileManager.getInputStreamById(Integer.parseInt(param.getImageId()));
            Sheet sheet = ExcelSupport.parseFile(fileInputStream, 0, EXCEL_TYPE_XLSX);
            map.put("headers", ExcelSupport.getSheetHeader(sheet, 0));
            map.put("list", ExcelParseHelper.parse2List(sheet, 1));
            return map;

        } finally {
            IOUtils.closeQuietly(fileInputStream);
        }
    }

    @Override
    public Map<String, Object> importExtEmp(ExtEmpImportParam param){

        Map<String, Object> apidatas = new HashMap<String, Object>();

        //excel文件id
        String imageId = Util.null2String(param.getImageId());
        Validate.notBlank(imageId, SalaryI18nUtil.getI18nLabel(542127, "imageId为空"));

        // 失败的数量
        int failCount = 0;
        // 成功的数量
        int successCount = 0;
        InputStream fileInputStream = null;
        try {
            fileInputStream = ImageFileManager.getInputStreamById(Integer.parseInt(param.getImageId()));

            Sheet sheet = ExcelSupport.parseFile(fileInputStream, 0, EXCEL_TYPE_XLSX);
            //数据库中现有非系统人员集合
            List<ExtEmpPO> allExtEmpInfo= getExternalEmployeeMapper().listAll();

            // 错误提示信息
            List<Map> excelComments = Lists.newArrayList();
            // 存在错误的那行数据
            List<Map<String, Object>> errorDatas = Lists.newArrayList();
            // 表头
            List<String> headers = ExcelSupport.getSheetHeader(sheet, 0);
            // 处理数值
            List<Map<String, Object>> data = ExcelParseHelper.parse2Map(sheet, 1);
            if (CollectionUtils.isEmpty(headers)) {
                throw new SalaryRunTimeException("表头为空");
            }
            if (CollectionUtils.isEmpty(data)) {
                throw new SalaryRunTimeException("无数据");
            }
            //存储待新增和待更新的ExtEmpPO数据
            List<ExtEmpPO> updateExtEmpPOList = new ArrayList<>();
            List<ExtEmpPO> insertExtEmpPOList = new ArrayList<>();
            //遍历excel表具体数据
            for (int i = 0; i < data.size(); i++) {

                String row = "第" + (i + 1) + "行";

                boolean isError = false;
                Map<String, Object> map = data.get(i);
                Long employeeId = 0L;

                String username = (String) map.getOrDefault(SalaryI18nUtil.getI18nLabel(25034, "姓名"), "");
                String departmentFullName = (String) map.getOrDefault(SalaryI18nUtil.getI18nLabel(27511, "部门"), "");
                String[] split = departmentFullName.split(">");
                String departmentName = split[split.length - 1];

                String subcompanyName = (String) map.getOrDefault(SalaryI18nUtil.getI18nLabel(33553, "分部"), "");
                String companystartdate = (String) map.getOrDefault(SalaryI18nUtil.getI18nLabel(1516, "入职日期"), "");

                //校验姓名
                if (StringUtils.isBlank(username)) {
                    //姓名是必填项
                    isError = true;
                    Map<String, String> errorMessageMap = Maps.newHashMap();
                    errorMessageMap.put("message", row + SalaryI18nUtil.getI18nLabel(102838, "姓名不能为空"));
                    excelComments.add(errorMessageMap);
                }
                long usernameNum = updateExtEmpPOList.stream().filter(f -> f.getUsername().equals(username)).count() + insertExtEmpPOList.stream().filter(f -> f.getUsername().equals(username)).count();
                if (usernameNum > 0) {
                    //excel中姓名相同时，只会录入第一次出现的数据
                    isError = true;
                    Map<String, String> errorMessageMap = Maps.newHashMap();
                    errorMessageMap.put("message", row + SalaryI18nUtil.getI18nLabel(102838, "本次excel文件中已存在该姓名相关数据，本行数据无法录入"));
                    excelComments.add(errorMessageMap);
                }
                //校验部门、分部
                List<SubCompanyInfo> subCompanyInfos = new ArrayList<>();
                List<DeptInfo> deptInfos = new ArrayList<>();
                List<DeptInfo> targetDeptRange = new ArrayList<>();
                if (StringUtils.isNotBlank(subcompanyName)) {
                    subCompanyInfos = getEmployMapper().getSubCompanyInfosByName(subcompanyName);
                    if (subCompanyInfos.size() == 0) {
                        isError = true;
                        Map<String, String> errorMessageMap = Maps.newHashMap();
                        errorMessageMap.put("message", row + SalaryI18nUtil.getI18nLabel(0,  "分部信息不存在，请检查分部数据是否正确"));
                        excelComments.add(errorMessageMap);
                    }
                }
                if (StringUtils.isNotBlank(departmentName)) {
                    List<DeptInfo>  toDealDeptInfos = getEmployMapper().getDeptInfosByName(departmentName);
                    //筛选出匹配导入部门全路径的部门信息
                    DepartmentComInfo dci = new DepartmentComInfo();
                    deptInfos = toDealDeptInfos.stream().filter(f -> {
                        try {
                            String departmentRealPath = dci.getDepartmentRealPath(f.getId().toString());
                            return departmentRealPath.contains(departmentFullName);
                        } catch (Exception e) {
                            throw new SalaryRunTimeException(e.getMessage());
                        }
                    }).collect(Collectors.toList());

                    if (deptInfos.size() == 0) {
                        isError = true;
                        Map<String, String> errorMessageMap = Maps.newHashMap();
                        errorMessageMap.put("message", row + SalaryI18nUtil.getI18nLabel(0,  "部门信息不存在，请检查部门数据是否正确"));
                        excelComments.add(errorMessageMap);
                    }
                }
                if (StringUtils.isNotBlank(companystartdate) && (companystartdate.length() < 10 || !SalaryDateUtil.checkDay(companystartdate.substring(0, 10)))) {
                    isError = true;
                    Map<String, String> errorMessageMap = Maps.newHashMap();
                    errorMessageMap.put("message", row + SalaryI18nUtil.getI18nLabel(0,  "入职日期格式错误，正确格式为YYYY-MM或者yyyy-MM-dd"));
                    excelComments.add(errorMessageMap);
                }

                if (!isError){
                    //校验当前数据是否有相关数据（姓名相同）存在数据库中，有则更新，无则新建
                    List<ExtEmpPO> targetExtEmpInfoList = allExtEmpInfo.stream().filter(f -> f.getUsername().equals(username)).collect(Collectors.toList());
                    //校验部门和分部关系
                    List<DeptInfo> targetDeptInfos = new ArrayList<>();
                    List<SubCompanyInfo> targetSubCompanyInfos = new ArrayList<>();
                    if (targetExtEmpInfoList.size() == 1) {
                        ExtEmpPO targetExtEmpInfo = targetExtEmpInfoList.get(0);
                        //将库中已有的部门和分布信息取出（excel行未设置对应字段数据时）
                        if (targetExtEmpInfo.getSubcompanyId() != null && subCompanyInfos.size() == 0) {
                            subCompanyInfos.add(SubCompanyInfo.builder().id(targetExtEmpInfo.getSubcompanyId()).name(targetExtEmpInfo.getSubcompanyName()).build());
                        }
                        if (targetExtEmpInfo.getDepartmentId() != null && deptInfos.size() == 0) {
                            DeptInfo oldDeptInfo = getEmployMapper().getDeptInfoById(targetExtEmpInfo.getDepartmentId());
                            deptInfos.add(oldDeptInfo);
                        }
                    }
                    //分部结果数为0，部门结果数大于1，则无法匹配
                    if(subCompanyInfos.size() == 0 && deptInfos.size() > 1) {
                        isError = true;
                        Map<String, String> errorMessageMap = Maps.newHashMap();
                        errorMessageMap.put("message", row + SalaryI18nUtil.getI18nLabel(0,  "系统中存在重复部门信息，无法指定当前人员关联的唯一部门，请细化部门上级部门或填写部门所属的分部信息来缩小部门筛选范围"));
                        excelComments.add(errorMessageMap);
                    } else if (subCompanyInfos.size() > 1 && deptInfos.size() == 0) {
                        //部门结果数为0，分部结果数大于1，则无法匹配
                        isError = true;
                        Map<String, String> errorMessageMap = Maps.newHashMap();
                        errorMessageMap.put("message", row + SalaryI18nUtil.getI18nLabel(0,  "系统中存在重复分部信息，无法指定当前人员关联的唯一分部，请通过填写人员所属的部门信息来缩小分部筛选范围"));
                        excelComments.add(errorMessageMap);
                    } else if (subCompanyInfos.size() >= 1 && deptInfos.size() >= 1) {
                        //部门结果数大于等于1，分部结果数大于等于1，筛选出可配对的组合，根据部门的所属分部字段进行配对
                        for (DeptInfo deptInfo : deptInfos) {
                            if (subCompanyInfos.stream().filter(g -> g.getId().equals(deptInfo.getSubcompanyid1())).count() > 0) {
                                targetDeptInfos.add(deptInfo);
                            }
                        }
                        if (targetDeptInfos.size() == 0) {
                            isError = true;
                            Map<String, String> errorMessageMap = Maps.newHashMap();
                            errorMessageMap.put("message", row + SalaryI18nUtil.getI18nLabel(0,  "部门与分部无法匹配"));
                            excelComments.add(errorMessageMap);
                        } else if (targetDeptInfos.size() > 1) {
                            isError = true;
                            Map<String, String> errorMessageMap = Maps.newHashMap();
                            errorMessageMap.put("message", row + SalaryI18nUtil.getI18nLabel(0,  "该组数据中的部门和分部信息在系统中出现多组匹配的部门和分部组合，无法指定唯一的部门和分部组合"));
                            excelComments.add(errorMessageMap);
                        } else {
                            targetSubCompanyInfos = subCompanyInfos.stream().filter(f -> f.getId().equals(targetDeptInfos.get(0).getSubcompanyid1())).collect(Collectors.toList());
                        }

                    } else if (subCompanyInfos.size() == 0 && deptInfos.size() == 1) {
                        //分部结果数为0，部门结果数为1，可以匹配
                        targetDeptInfos.add(deptInfos.get(0));
                    } else if (subCompanyInfos.size() == 1 && deptInfos.size() == 0) {
                        //部门结果数为0，分部结果数为1，可以匹配
                        targetSubCompanyInfos.add(subCompanyInfos.get(0));
                    }
                    //收集excel有效数据，并区分新增和更新
                    DeptInfo finalDeptInfo = targetDeptInfos.size() > 0 ? targetDeptInfos.get(0) : null;
                    SubCompanyInfo finalSubCompanyInfo = targetSubCompanyInfos.size() > 0 ? targetSubCompanyInfos.get(0) : null;
                    if (targetExtEmpInfoList.isEmpty()) {
                        if (!isError) {
                            //添加一条新建数据
                            insertExtEmpPOList.add(handleExtEmpInfo(null, map, finalDeptInfo, finalSubCompanyInfo));
                        }
                    } else if (targetExtEmpInfoList.size() > 1) {
                        isError = true;
                        Map<String, String> errorMessageMap = Maps.newHashMap();
                        errorMessageMap.put("message", row + SalaryI18nUtil.getI18nLabel(0,  "数据库中非系统人员信息存在姓名相同数据，请先确保姓名唯一"));
                        excelComments.add(errorMessageMap);
                    } else {
                        if (!isError) {
                            //添加一条更新数据
                            updateExtEmpPOList.add(handleExtEmpInfo(targetExtEmpInfoList.get(0), map, finalDeptInfo, finalSubCompanyInfo));
                        }
                    }

                }

                if (isError) {
                    failCount++;
                    errorDatas.add(map);
                } else {
                    successCount++;
                }

            }
            //更新
            for(ExtEmpPO po : updateExtEmpPOList) {
                getExternalEmployeeMapper().updateIgnoreNull(po);

                // 记录日志
                LoggerContext<ExtEmpPO> loggerContext = new LoggerContext<>();
                loggerContext.setUser(user);
                loggerContext.setTargetId(String.valueOf(po.getId()));
                loggerContext.setTargetName(po.getUsername());
                loggerContext.setOperateType(OperateTypeEnum.UPDATE.getValue());
                loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "导入-更新非系统人员"));
                loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "导入-更新非系统人员") + ": " + po.getUsername());
                loggerContext.setNewValues(po);
                SalaryElogConfig.extEmployeeLoggerTemplate.write(loggerContext);
            }
            //新建
            for(ExtEmpPO po : insertExtEmpPOList) {
                getExternalEmployeeMapper().insertIgnoreNull(po);

                // 记录日志
                LoggerContext<ExtEmpPO> loggerContext = new LoggerContext<>();
                loggerContext.setUser(user);
                loggerContext.setTargetId(String.valueOf(po.getId()));
                loggerContext.setTargetName(po.getUsername());
                loggerContext.setOperateType(OperateTypeEnum.ADD.getValue());
                loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "导入-新增非系统人员"));
                loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "导入-新增非系统人员") + ": " + po.getUsername());
                loggerContext.setNewValues(po);
                SalaryElogConfig.extEmployeeLoggerTemplate.write(loggerContext);
            }


            apidatas.put("successCount", successCount);
            apidatas.put("errorCount", failCount);
            apidatas.put("errorData", excelComments);

        } finally {
            IOUtils.closeQuietly(fileInputStream);
        }
        return apidatas;
    }

    public ExtEmpPO handleExtEmpInfo(ExtEmpPO po, Map<String, Object> map, DeptInfo deptInfo, SubCompanyInfo subCompanyInfo) {
        ExtEmpPO resultPo = new ExtEmpPO();
        if (po == null) {
            //新建
            resultPo.setId(IdGenerator.generate());
            resultPo.setStatus("2");
            resultPo.setCreateTime(new Date());
            resultPo.setUpdateTime(new Date());
            resultPo.setDeleteType(0);
            resultPo.setCreator((long) user.getUID());
        } else {
            //更新
            BeanUtils.copyProperties(po, resultPo);
            resultPo.setUpdateTime(new Date());
        }
        String username = (String) map.getOrDefault(SalaryI18nUtil.getI18nLabel(25034, "姓名"), "");
//        String departmentName = (String) map.getOrDefault(SalaryI18nUtil.getI18nLabel(27511, "部门"), "");
//        String subcompanyName = (String) map.getOrDefault(SalaryI18nUtil.getI18nLabel(33553, "分部"), "");
        String companystartdate = (String) map.getOrDefault(SalaryI18nUtil.getI18nLabel(1516, "入职日期"), "");
        String mobile = (String) map.getOrDefault(SalaryI18nUtil.getI18nLabel(125238, "手机号"), "");
        String workcode = (String) map.getOrDefault(SalaryI18nUtil.getI18nLabel(1933, "工号"), "");
        String idNo = (String) map.getOrDefault(SalaryI18nUtil.getI18nLabel(1887, "身份证号码"), "");
        String bankCardNum = (String) map.getOrDefault(SalaryI18nUtil.getI18nLabel(0, "本人开户的银行卡卡号"), "");
        String bankName = (String) map.getOrDefault(SalaryI18nUtil.getI18nLabel(0, "本人开户的银行卡开户支行全称"), "");

        if (StringUtils.isNotBlank(companystartdate)) {
            resultPo.setCompanystartdate(companystartdate.substring(0, 10));
        }

        if (StringUtils.isNotBlank(username)) {
            resultPo.setUsername(username);
        }
        if (StringUtils.isNotBlank(mobile)) {
            resultPo.setMobile(mobile);
        }
        if (StringUtils.isNotBlank(workcode)) {
            resultPo.setWorkcode(workcode);
        }
        if (StringUtils.isNotBlank(idNo)) {
            resultPo.setIdNo(idNo);
        }
        if (StringUtils.isNotBlank(bankCardNum)) {
            resultPo.setBankCardNum(bankCardNum);
        }
        if (StringUtils.isNotBlank(bankName)) {
            resultPo.setBankName(bankName);
        }
        if (deptInfo != null) {
            resultPo.setDepartmentName(deptInfo.getName());
            resultPo.setDepartmentId(deptInfo.getId());
        }
        if (subCompanyInfo != null) {
            resultPo.setSubcompanyName(subCompanyInfo.getName());
            resultPo.setSubcompanyId(subCompanyInfo.getId());
        }
        if (resultPo.getDepartmentName() == null) {
            resultPo.setDepartmentName("");
        }
        resultPo.setModifier((long) user.getUID());
        return resultPo;
    }

    @Override
    public List<DataCollectionEmployee> listBySubCompanyOrDepartment(List<Long> subCompanyIds, List<Long> departmentIds) {
        return getExternalEmployeeMapper().listSomeDataCollectionEmployee(ExtEmpPO.builder().subcompanyIds(subCompanyIds).departmentIds(departmentIds).build());
    }
}
